import { Callout } from '@/components'

# Suspense

@suspensive/react's `<Suspense/>` will be just [Suspense of original React](https://react.dev/reference/react/Suspense).

### props.fallback

fallback works the same as fallback of original React's Suspense.

```tsx /Suspense/
import { Suspense } from '@suspensive/react'

const Example = () => (
  <Suspense fallback={<Loading />}>
    <Children />
  </Suspense>
)
```

<Callout>

Default fallback

`<Suspense/>` are more powerful when used with `<DefaultPropsProvider/>`.
Control multiple `<Suspense/>`s default fallback with `<DefaultPropsProvider/>`. Details are introduced in [`<DefaultPropsProvider/>` page](/docs/react/DefaultPropsProvider).

</Callout>

### Avoid Server side rendering (clientOnly)

If you use clientOnly prop, `<Suspense/>` will return fallback in server and return children in client.

```tsx /clientOnly/
import { Suspense } from '@suspensive/react'

const Example = () => (
  <Suspense clientOnly fallback={<Loading />}>
    <Children />
  </Suspense>
)
```

When using the clientOnly prop, the useIsClient hook is used internally, and useIsClient uses getSnapshot and getServerSnapshot of useSyncExternalStore to ensure that it is a client.

```tsx /useIsClient/
const useIsClient = () =>
  useSyncExternalStore(emptySubscribe, getSnapshot, getServerSnapshot)

const emptySubscribe = () => noop
const getSnapshot = () => true
const getServerSnapshot = () => false
```

https://x.com/TkDodo/status/1741068994981826947?t=XmG17etMUL2m0JFim03vqw&s=19

<Callout type='info'>

Migration support SSR gradually (`<Suspense clientOnly/>` -> `<Suspense/>`)

If you want to use Suspense working in both SSR/CSR, You can change `<Suspense clientOnly/>` to `<Suspense/>` gradually.

</Callout>

## Suspense.with

`Suspense.with` is a higher-order component (HOC) that allows you to wrap a component with a Suspense boundary.
`Suspense.with` makes it easy to wrap a component.

```tsx /Suspense.with/
import { Suspense } from '@suspensive/react'

const Example = Suspense.with({ fallback: <Spinner /> }, () => {
  // code make suspending

  return <>...</>
})
```
